package {{.ModuleName}}impl

import (
    "context"
	"errors"
	"fmt"
	"go-caipu/pkg/infra/log"
	"go-caipu/pkg/services/{{.PackageName}}/{{.ModuleName}}"
	"go-caipu/pkg/services/{{.PackageName}}/{{.ModuleName}}/models"
	"go-caipu/pkg/services/dto"
	"gorm.io/gorm"
)

type store interface {
	Get{{.ClassName}}Page(ctx context.Context,cmd {{.ModuleName}}.Get{{.ClassName}}PageCommand) (data []{{.ModuleName}}.{{.ClassName}}, num int64, err error)
	Get(ctx context.Context,cmd {{.ModuleName}}.Get{{.ClassName}}Command) ({{.ModuleName}}.{{.ClassName}}, error)
	Insert(ctx context.Context,post {{.ModuleName}}.{{.ClassName}}) error
	Update(ctx context.Context,post {{.ModuleName}}.{{.ClassName}}) error
	Remove(ctx context.Context,cmd {{.ModuleName}}.Remove{{.ClassName}}Command) error
}
type sqlStore struct {
	db     *gorm.DB
	logger log.Logger
}

func ProvideStore(db *gorm.DB) sqlStore {
	return sqlStore{
		db:     db,
		logger: log.New("dept.store"),
	}
}

func (s sqlStore) Get{{.ClassName}}Page(ctx context.Context,cmd {{.ModuleName}}.Get{{.ClassName}}PageCommand) (result []{{.ModuleName}}.{{.ClassName}}, num int64, err error) {
	var items []models.{{.ClassName}}
	err = s.db.Model(&models.{{.ClassName}}{}).Scopes(
		dto.MakeCondition(cmd.GetNeedSearch()),
		dto.Paginate(cmd.GetPageSize(), cmd.GetPageIndex()),
	).Find(&items).Limit(-1).Offset(-1).Count(&num).Error
	if err != nil {
		return
	}
	for _, v := range items {
    		result = append(result, ConvertToDTO(v))
    }
	return
}
func ConvertToDTO(model models.{{.ClassName}}) {{.ModuleName}}.{{.ClassName}} {
	result := {{.ModuleName}}.{{.ClassName}}{
		    {{ range .Columns -}}
            {{- if eq .GoField "CreatedAt" -}}
            {{- else if eq .GoField "UpdatedAt" -}}
            {{- else if eq .GoField "DeletedAt" -}}
            {{- else if eq .GoField "CreateBy" -}}
            {{- else if eq .GoField "UpdateBy" -}}
            {{- else }}
            {{.GoField}}: model.{{.GoField}},
            {{- end }}
            {{- end }}
		ControlBy:  model.ControlBy,
		ModelTime:  model.ModelTime,
	}
	return result
}
func (s sqlStore) Get(ctx context.Context,cmd {{.ModuleName}}.Get{{.ClassName}}Command) (result {{.ModuleName}}.{{.ClassName}},err error) {
	var data models.{{.ClassName}}
	err = s.db.Model(&data).First(&data, cmd.{{.PkGoField}}).Error
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		err=errors.New(fmt.Sprintf("{{.PkGoField}}=%d record Not found", cmd.{{.PkGoField}}))
		return
	}
	if err != nil {
		s.logger.Log(fmt.Sprintf("get  {{.ModuleName}}=%d  error:%s",cmd.{{.PkGoField}} ,err.Error()))
		return
	}
    return ConvertToDTO(data), nil
}
func ConvertToDT(model {{.ModuleName}}.{{.ClassName}},cmd *models.{{.ClassName}}) {

		    {{ range .Columns -}}
            {{- if eq .GoField "CreatedAt" -}}
            {{- else if eq .GoField "UpdatedAt" -}}
            {{- else if eq .GoField "DeletedAt" -}}
            {{- else if eq .GoField "CreateBy" -}}
            {{- else if eq .GoField "UpdateBy" -}}
            {{- else }}
            cmd.{{.GoField}}= model.{{.GoField}}
            {{- end }}
            {{- end }}
}

func (s sqlStore) Insert(ctx context.Context,cmd {{.ModuleName}}.{{.ClassName}}) (err error) {
	tx := s.db.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	var data models.{{.ClassName}}
    ConvertToDT(cmd, &data)
    data.CreatedAt = cmd.CreatedAt
    data.CreateBy = cmd.CreateBy

	err = tx.Create(&data).Error
	if err != nil {
		s.logger.Log(fmt.Sprintf("insert  {{.ModuleName}}  error:%s",  err.Error()))
		return err
	}
	return nil
}

func (s sqlStore) Update(ctx context.Context,cmd {{.ModuleName}}.{{.ClassName}}) (err error) {
	tx := s.db.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
    //查询当前部门名称是否存在
	var data models.{{.ClassName}}
	err = s.db.Model(&data).First(&data, cmd.{{.PkGoField}}).Error
	if err != nil {
		s.logger.Log(fmt.Sprintf("check {{.ClassName}} id=%d is exists error:%s", cmd.Id, err.Error()))
		return err
	}
	ConvertToDT(cmd, &data)
	data.UpdatedAt = cmd.UpdatedAt
	data.UpdateBy = cmd.UpdateBy
	err = tx.Save(&data).Error
	if err != nil {
		s.logger.Log(fmt.Sprintf("update  {{.ModuleName}}  error:%s",  err.Error()))
		return err
	}
	return nil
}

func (s sqlStore) Remove(ctx context.Context,cmd {{.ModuleName}}.Remove{{.ClassName}}Command) (err error) {
	tx := s.db.Begin()
	defer func() {
		if err != nil {
			tx.Rollback()
		} else {
			tx.Commit()
		}
	}()
	var data models.{{.ClassName}}
	err = tx.Model(&models.{{.ClassName}}{}).Delete(&data, cmd.Ids).Error
	if err != nil {
		return err
	}
	return
}
